/*
-----------------------------------------------------------------------------
This source file is part of the OGRE Reference Application, a layer built
on top of OGRE(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#ifndef __REFAPP_PLAYERBASE_H__
#define __REFAPP_PLAYERBASE_H__


#include "OgreRefAppApplicationObject.h"
#include "OgreRefAppSteeringBehaviors.h"
#include "OgreRefAppRegion.h"
#include "OgreRefAppSoccerTeam.h"
#include "OgreRefAppSoccerPitch.h"



namespace OgreRefApp
{
    class SoccerTeam;
    class PlayerBase : public ApplicationObject
    {

    public:

        enum player_role{goal_keeper, attacker, defender};

    protected:
        //this player's role in the team
        player_role             m_PlayerRole;
        SteeringBehavior* m_pSterringBehavior;

        //a pointer to this player's team
        SoccerTeam*             m_pTeam;

        //the region that this player is assigned to.
        Region*                     m_iHomeRegion;

        //the region this player moves to before kickoff
        Region*                       m_iDefaultRegion;

        //the distance to the ball (in squared-space). This value is queried
        //a lot so it's calculated once each time-step and stored here.
        Real                   m_dDistSqToBall;

    public:
        PlayerBase(const String& name, player_role    role );
        ~PlayerBase();

        SteeringBehavior* getSteeringBehavior()
        {
            return m_pSterringBehavior;
        }

        void        SetDistSqToBall(Real val)
        {
            m_dDistSqToBall = val;
        }

        //returns true if there is an opponent within this player's
        //comfort zone
        bool        isThreatened();

        //rotates the player to face the ball or the player's current target
        void        TrackBall();
        void        TrackTarget();



        //returns true if the ball can be grabbed by the goalkeeper
        bool        BallWithinKeeperRange();

        //returns true if the ball is within kicking range
        bool        BallWithinKickingRange();

        //returns true if a ball comes within range of a receiver
        bool        BallWithinReceivingRange();

        //returns true if the player is located within the boundaries
        //of his home region
        bool        InHomeRegion();

        //returns true if this player is ahead of the attacker
        bool        isAheadOfAttacker();

        //returns true if a player is located at the designated support spot
        bool        AtSupportSpot();

        //returns true if the player is located at his steering target
        bool        AtTarget();

        //returns true if the player is the closest player in his team to
        //the ball
        bool        isClosestTeamMemberToBall();

        //returns true if the point specified by 'position' is located in
        //front of the player
        bool        PositionInFrontOfPlayer(Ogre::Vector3   position);

        //returns true if the player is the closest player on the pitch to the ball
        bool        isClosestPlayerOnPitchToBall();

        //returns true if this player is the controlling player
        bool        isControllingPlayer();

        //returns true if the player is located in the designated 'hot region' --
        //the area close to the opponent's goal
        bool        InHotRegion();

        player_role Role()
        {
            return m_PlayerRole;
        }

        double       DistSqToBall()
        {
            return m_dDistSqToBall;
        }
        void        SetDistSqToBall(double val)
        {
            m_dDistSqToBall = val;
        }

        //calculate distance to opponent's/home goal. Used frequently by the passing
        //methods
        double       DistToOppGoal();
        double       DistToHomeGoal();

        void        SetDefaultHomeRegion()
        {
            m_iHomeRegion = m_iDefaultRegion;
        }

        void        FindSupport();

        Ball*      getBall();
        SoccerPitch*     Pitch();
        SteeringBehavior*  Steering()
        {
            return m_pSterringBehavior;
        }
        Region*    HomeRegion();
        void                     SetHomeRegion(Region*   NewRegion)
        {
            m_iHomeRegion = NewRegion;
        }

        void SetHomeRegion(int NewRegion);

        SoccerTeam*       Team()
        {
            return m_pTeam;
        }

    };


}

#endif


